<template>
  <a-form-item :label="formItem.label" :field="formItem.field" v-bind="formItem.formItem">
    <a-row v-if="formItem.onlyItem && formItem.content" :gutter="16">
      <a-col v-for="innerItem in formItem.content" v-bind="innerItem.col">
        <BaseFormItem :form-item="innerItem" />
      </a-col>
    </a-row>
    <component
      v-else
      v-bind="omit(formItem.props, 'min')"
      :is="getDynamicComponent(formItem.component, formItem.render)"
      :options="formItem.options"
      :data="formItem.data"
      :placeholder="createPlaceholer(formItem.label, formItem.component, formItem.placeholder)"
      :max="handleLinkageValue(formItem, true)"
      :min="handleLinkageValue(formItem, false)"
      :modelValue="get(formModel, formItem.field)"
      @update:modelValue="(value: any) => set(formModel, formItem.field, value)"
    />
  </a-form-item>
</template>

<script setup lang="ts">
import { InputNumberInstance } from "@arco-design/web-vue";
import components from "../components";
import { FORM_MODEL_KEY } from "../config";
import { FormItem, FormComponent } from "../types";
import { get, isNumber, isString, omit, set } from "lodash-es";

defineProps<{
  formItem: FormItem;
}>();

const formModel = inject(FORM_MODEL_KEY)!;

/**
 * 获取 min 和 max 的表单联动数值
 * @param item 表单项信息
 * @param isMax 是否是获取 max 联动数值
 */
const handleLinkageValue = (item: FormItem, isMax: boolean) => {
  const min = (item.props as InputNumberInstance["$props"])?.min;
  const max = (item.props as InputNumberInstance["$props"])?.max;
  if (!min && !max) return;
  if (isMax) {
    if (isNumber(max)) return max;
    if (isString(max)) return get(formModel.value, max);
  } else {
    if (isNumber(min)) return min;
    if (isString(min)) return get(formModel.value, min);
  }
};

const getDynamicComponent = (
  component: FormComponent | undefined,
  render: (() => Component) | undefined
) => {
  if (component) return components[component];
  if (render) return render();
  new Error("请传递 type 或者 render");
  return "";
};

/**
 *
 * @param formItemProps
 * @param componentProps
 */
const createPlaceholer = (
  label: string | undefined,
  component: FormComponent | undefined,
  placeholder?: string
) => {
  let prefix = undefined;
  switch (component) {
    case "Input":
    case "InputPassword":
    case "InputNumber":
    case "Textarea":
      prefix = "请输入";
      break;
    case "Select":
    case "InputTag":
      prefix = "请选择";
      break;
    default:
      return;
  }
  return placeholder ?? `${prefix}${label}`;
};
</script>

<style scoped></style>
